package com.dcits.business.report;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.dcits.tool.RmpUtil;
import com.dcits.tool.StringUtils;

/**
 * 资源数据分析工具
 * @author xuwangcheng
 * @version 2018.5.11
 *
 */
public class AnalyzeUtil {
	/**
	 * 获取文件中所有数据并进行分析转换成AnalyzeInfoData对象集合
	 * @param fileInfo 文件保存的所有信息
	 * @param itemNames 类目
	 * @param constant 注释
	 * @param testTime 截取时间范围
	 * @return
	 */
	public static Map<String, List<AnalyzeInfoData>> analyzeAllFileInfo(JSONObject fileInfo, JSONObject itemNames, JSONObject constant, String testTime) {
		Map<String, List<AnalyzeInfoData>> analyzeInfoDatas = new HashMap<String, List<AnalyzeInfoData>>();
		JSONObject serverList = fileInfo.getJSONObject("serverList");
		
		String[] times = testTime.split("~");
		Long beginTime = RmpUtil.parseStrToDate(times[0].trim()).getTime();
		Long endTime = RmpUtil.parseStrToDate(times[1].trim()).getTime();
		
		for (String key:serverList.keySet()) {
			List<AnalyzeInfoData> datas = analyzeInfoDatas.get(key);
			if (datas == null) {
				datas = new ArrayList<AnalyzeInfoData>();
				analyzeInfoDatas.put(key, datas);
			}
			
			JSONArray arrays = serverList.getJSONArray(key);
			for (Object server:arrays) {
				JSONObject serverObj = JSONObject.parseObject(server.toString());	
				
				AnalyzeInfoData analyzeInfoData = new AnalyzeInfoData(serverObj.getInteger("viewId"),
						serverObj.getString("host") , key, null);
				analyzeInfoData.analyzeInfo(itemNames.getJSONArray(key), fileInfo, beginTime, endTime);
				datas.add(analyzeInfoData);
			}
			
		}
				
		return analyzeInfoDatas;
	}
	
	/**
	 * 非功能性测试资源数据创建
	 * @param analyzeDatas
	 * @param apiData
	 * @param serverList
	 * @return
	 */
	public static JSONObject createNonFunctionalTestResourceObject(JSONObject serverList) {
		JSONObject object = new JSONObject();
		object.put("applicationResources", new JSONArray());
		object.put("databaseResources", new JSONArray());
		object.put("clusterResources", new JSONArray());
		
		for (String resourceType:serverList.keySet()) {
			JSONArray array = serverList.getJSONArray(resourceType);
			for (Object obj:array) {
				JSONObject viewInfo = (JSONObject) obj;
				
				JSONObject defaultData = viewInfo.getJSONObject("apiData");
				if (defaultData == null) continue;

				for (String itemName:defaultData.keySet()) {
					defaultData.getJSONObject(itemName).remove("mapper");
				}				
				object.getJSONArray(resourceType).add(defaultData);
			}
		}
		
		return object;
	}
	
	/**
	 * 获取时间范围<br>
	 * 格式：2018-05-09 00:00:00 ~ 2018-06-14 00:00:00
	 * @param fileInfo
	 * @return
	 */
	public static JSONObject getMonitoringRangeTime(JSONObject fileInfo) {
		Date endTime = null;
		Date beginTime = null;
		JSONObject serverList = fileInfo.getJSONObject("serverList");
		for (String key:serverList.keySet()) {
			for (Object o:serverList.getJSONArray(key)) {
				JSONObject serverInfo = (JSONObject) o;
				if (beginTime == null || (beginTime != null && (beginTime.getTime() > serverInfo.getDate("startTime").getTime()))) {
					beginTime = serverInfo.getDate("startTime");
				}
				if (endTime == null || (endTime != null && (endTime.getTime() < serverInfo.getDate("lastTime").getTime()))) {
					endTime = serverInfo.getDate("lastTime");
				}
			}
		}
		if (endTime == null || beginTime == null) {
			return null;
		}
		JSONObject returnTime = new JSONObject();
		returnTime.put("min", RmpUtil.formatDate(beginTime, RmpUtil.FULL_DATE_PATTERN));
		returnTime.put("max", RmpUtil.formatDate(endTime, RmpUtil.FULL_DATE_PATTERN));
		return returnTime;
	}
	
	/**
	 * 创建资源列表，已经绑定分析了的数据和默认数据
	 * @param analyzeDatas
	 * @param apiData
	 * @param serverList
	 * @return
	 */
	public static JSONObject createBindedDataServerInfoObject(Map<String, List<AnalyzeInfoData>> analyzeDatas,
			JSONObject apiData, JSONObject serverList) {
		for (String serverType:serverList.keySet()) {
			JSONArray typeArrays = serverList.getJSONArray(serverType);
			for (Object o:typeArrays) {
				JSONObject server = (JSONObject) o;
				JSONObject defaultApiData = JSON.parseObject(JSON.toJSONString(apiData), JSONObject.class);
				bindDefaultApiData(defaultApiData, filterAnalyzeInfoData(analyzeDatas, serverType, server.getInteger("viewId")), serverType);
				server.put("apiData", defaultApiData);
			}
		}				
		return serverList;
	}
	
	private static void bindDefaultApiData(JSONObject defaultApiData, AnalyzeInfoData analyzeData, String serverType) {
		for (String key:defaultApiData.keySet()) {
			JSONObject data = defaultApiData.getJSONObject(key);
			for (String name:data.keySet()) {
				JSONObject apiData = data.getJSONObject(name);
				getDefailtApiDataValue(apiData, analyzeData.getItems(), serverType);
			}
			data.getJSONObject("host").put("value", analyzeData.getHost());
			data.getJSONObject("serverType").put("value", analyzeData.getServerType());
			data.getJSONObject("tags").put("value", analyzeData.getTags());
		}
	}
	
	private static void getDefailtApiDataValue(JSONObject apiData, List<AnalyzeItemData> analyzeItemDatas, String serverType) {
		String value = "";
		if (apiData.getJSONObject("mapper") != null) {
			JSONArray mappers = apiData.getJSONObject("mapper").getJSONArray(serverType);			
			if (mappers != null) {
				String[] signs = apiData.getString("sign").split(",");
				for (int i = 0;i < mappers.size();i++) {
					String avgValue = filterAnalyzeItemDataValue(analyzeItemDatas, mappers.getString(i).toString());
					if (avgValue != null) {
						if ("linux".equalsIgnoreCase(serverType) && mappers.getString(i).toString().matches("freeCpu|freeMem")) {
							avgValue = String.format("%.2f", 100 - Double.parseDouble(avgValue));
						}
						value += avgValue + signs[i] + ",";
					}					
				}
			}
		}	
		
		if (StringUtils.isNotEmpty(value)) {
			apiData.put("value", value.substring(0, value.length() - 1));
		}
	}
	
	private static String filterAnalyzeItemDataValue(List<AnalyzeItemData> analyzeItemDatas, String itemName) {
		for (AnalyzeItemData data:analyzeItemDatas) {
			if (data.getItemName().equals(itemName)) {
				return data.getAvgValue();
			}
		}
		
		return null;
	}
	
	
	private static AnalyzeInfoData filterAnalyzeInfoData(Map<String, List<AnalyzeInfoData>> analyzeDatas, String serverType, Integer viewId) {
		List<AnalyzeInfoData> typeAnalyzeDatas = analyzeDatas.get(serverType);
		if (typeAnalyzeDatas != null) {
			for (AnalyzeInfoData data:typeAnalyzeDatas) {
				if (data.getViewId().equals(viewId)) {
					return data;
				}
			}
		}
		
		return null;
	}
}
